/**
  ******************************************************************************
  * @file    devInit.c
  * @author  Silan - MC Team
  * @version 1.0.0
  * @date    2017/07/19
  * @brief   Device Init Source File
  * @details None
  * @note    None
  ******************************************************************************
  * @attention
  * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  * AS A RESULT, SILAN MICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  ******************************************************************************
  * Change History
  * -# 2017/07/19 | v1.0.0 | Wangjianlong | Creat file.
  *
  ******************************************************************************
  */

/**
   @mainpage SILAN PMSM Motor Software Library
   *
   * <b>Introduction</b>
   *
   * This user manual describes the PMSM motor software library,developer only change
   * correspond parameter and use some API function
   *
   * The library is divided into a number of functions each covering a specific category:
   * - Basic motor axis transfer functions
   * - Motor control functions
   * - PFC control functions
   * - User interfce function
   * - debug Tool function

   *
   * <b>Examples</b>
   *
   * The library
   *
   *
   * <b>Copyright Notice</b>
   *
   * Copyright (C) 2010-2013 Silan Limited. All rights reserved.
   */


/** @page PMSM motor control module
  this modele include:

   @li pfc module ,user only init PFC module and set correspond parameter:
       - pfc param init at PfcParaSwtich.c named PfcParaSwitch() function.
       - pfc control state at PfcStateSwitch.c named PfcStateSwitch() function.
       - pfc control slow loop at PfcCtrl.c named PfcFastTask() function.
       - pfc control fast loop at PfcCtrl.c named PfcSlowTask() function.

   @li motor module ,user only init mortor module and set correspond parameter:
       - motor param init at pmsmCtrl.c named PMSM_PmsmInit() function.
       - motor state control at pmsmCtrl.c named mg_MotorStateCtrl() function.
       - motor control slow loop at pmsmCtrl.c named mg_LowIsr() function.
       - motor control fast loop at pmsmCtrl.c named mg_HighIsr() function.

   @li debug tool module, user only change low level uart code and change data for transfer:
       - user only modify arrry and function at dbgCmd.c named g_pParamsTable[] array and CMD_CmdProcess() function
 */

/*******************************************************************************
 * Include file
 ******************************************************************************/
#include "system_SC32F58128.h"
#include "MultCtrl.h"
#include "DivCtrl.h"
#include "SC32F58128_SysClkCfg.h"
#include "SC32F58128_Timer.h"

#include "devInit.h"
#include "BSP_uart.h"
#include "BSP_adc.h"
#include "BSP_pwm.h"
#include "BSP_gpio.h"
#include "BSP_dma.h"

#include "eev_ctl.h"
#include "iic_soft.h"

#include "api_fan_pmsm_pfc.h"
#include "api_dbg.h"

/*******************************************************************************
 * Global data for the project
 ******************************************************************************/
uint8_t  g_u8EepromErrFlg = 0;

/*******************************************************************************
 * Local data for the current file
 ******************************************************************************/
//#define EEPROM_READ_EN    0

uint8_t mg_u8EepromWriteData[] = {
0xAA, 0x83, 0x04, 0x00, 0xAC, 0x58, 0x58, 0x58, 0x14, 0x3C, 0x4E, 0x55, 0x37, 0x5A, 0x1E, 0x3C,
0x50, 0x09, 0x19, 0x3A, 0x52, 0x07, 0x25, 0x4C, 0x5A, 0x11, 0x03, 0x01, 0x02, 0x03, 0x03, 0x01,
0x02, 0x03, 0x03, 0x32, 0x2C, 0x25, 0x1E, 0x0A, 0x2D, 0x5A, 0x0A, 0x12, 0x01, 0x08, 0x12, 0x05,
0x08, 0x12, 0x05, 0x0C, 0x24, 0x3C, 0x14, 0x0F, 0x14, 0x06, 0x1E, 0x6F, 0x66, 0x60, 0x3C, 0xA6,
0x98, 0x8E, 0x14, 0x53, 0x4C, 0x48, 0x14, 0x28, 0x32, 0x38, 0x1E, 0x1E, 0x0A, 0x8E, 0x7B, 0x44,
0x34, 0x82, 0x73, 0x54, 0x28, 0x14, 0x1D, 0x46, 0x4B, 0x70, 0x50, 0x50, 0x6B, 0x46, 0x50, 0x6E,
0x64, 0x64, 0x64, 0x32, 0x6E, 0x65, 0x62, 0x61, 0x15, 0xBE, 0x0C, 0xDC, 0x5C, 0x23, 0x7D, 0x7D,
0x7D, 0x78, 0x78, 0x19, 0x5A, 0x1E, 0x23, 0x28, 0x37, 0x16, 0x0F, 0x23, 0x28, 0x2D, 0x37, 0x1E,
0x19, 0x3C, 0x02, 0x3C, 0x3C, 0x3C, 0x28, 0xFF, 0x1E, 0x14, 0x78, 0x3C, 0xFA, 0x28, 0x14, 0x0F,
0xB4, 0xA0, 0x00, 0x14, 0x16, 0x28, 0x17, 0x14, 0x01, 0x03, 0x23, 0x16, 0x4B, 0x3E, 0x16, 0x3C,
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x14, 0x1E, 0x26, 0x0E, 0x15, 0x05, 0x64, 0x03,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x2D, 0x03, 0x00, 0x00, 0x00, 0x3C, 0x27, 0x3C,
0x57, 0x5C, 0x1E, 0xC8, 0x41, 0x5A, 0x4B, 0x0F, 0x53, 0x4B, 0x23, 0x21, 0x0F, 0x14, 0x46, 0x08,
0x48, 0x17, 0x0F, 0x08, 0x01, 0x1E, 0x0A, 0x06, 0x03, 0x14, 0x00, 0x05, 0x1F, 0x40, 0x00, 0x3A,
0x00, 0x17, 0x01, 0x69, 0x28, 0x50, 0x00, 0x60, 0x00, 0x33, 0x01, 0x60, 0x1E, 0x78, 0x00, 0x92,
0x00, 0x50, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x09, 0x05,
0xAA, 0x00, 0x00, 0x08, 0x11, 0x5A, 0x35, 0x0A, 0x4B, 0x50, 0x41, 0x30, 0x00, 0x64, 0x56, 0x5A,
0x5A, 0x3D, 0x4B, 0x41, 0x30, 0x00, 0x28, 0x14, 0x05, 0x05, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//0x55, 0xAA, 0x4A, 0x01, 0xF6, 0x01, 0xCE, 0x04, 0x0C, 0x00, 0xC4, 0x09, 0x5E, 0x01, 0x52, 0x03,
//0x59, 0x00, 0x7F, 0x00, 0xC0, 0x04, 0x54, 0x01, 0x03, 0xF6, 0x01, 0xAD, 0x00, 0x78, 0x00, 0x32,
//0x32, 0x5A, 0x00, 0x78, 0x00, 0x14, 0x4C, 0x1D, 0x1E, 0x00, 0x2B, 0x93, 0x00, 0x7E, 0x06, 0xAA,
//0x03, 0x00, 0x50, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x28, 0x00, 0x14, 0x00, 0xD0, 0x07, 0xAA,
//0xD0, 0x07, 0x2C, 0x01, 0xB8, 0x0B, 0xB8, 0x0B, 0x11, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/*******************************************************************************
 * Local prototypes function
 ******************************************************************************/
void mg_DeviceSystemInit(void);
void mg_DevicePeripheralInit(void);
void mg_CacheInit(void);
void mg_WdtInit(void);
//void mg_TimerInit(void);
void mg_EruInit(void);
void mg_ReadIIcData(void);
void mg_SetIRQ(void);
void mg_SetIRQ_c1(void);

/*******************************************************************************
 * Local function for the current file
 ******************************************************************************/

/**
  * @brief  Cache Initialization.
  */
void mg_CacheInit(void)
{
  CACHE->CACHE_CTRL_b.AUTOCLEAR = 1;                /**< Enable Cache Auto Clear Function  */
  while(CACHE->CACHE_CTRL_b.AUTOCLEAR_END == 0);
  CACHE->CACHE_CTRL_b.AUTOCLEAR_END = 1;

  CACHE->MAIN_CTRL_b.CACHE_EN = 1;                  /**< Enable Cache                      */
  CACHE->CACHE_CTRL_b.STATISTICS_EN = 1;            /**< Enable Cache Hit Count            */

  ACCESS_ENABLE;
  SYSREG->PREFETCH_CFG_b.PREFETCH_EN = 1;           /**< Prefetch Enable                   */
  SYSREG->PREFETCH_CFG_b.ONLY_CACHE = 1;            /**< Only Cache Enable                 */
  SYSREG->PREFETCH_CFG_b.PREFETCH_INFO_RST = 1;     /**< Reset Prefect Information         */
  SYSREG->PREFETCH_CFG_b.PREFETCH_INFO_RST = 0;
  ACCESS_DISABLE;
}

/**
  * @brief  Watch Dog Timer Initialization.
*/
void mg_WdtInit(void)
{
//  WDT0->WDOGLOAD = 0xffffffff;
  WDT0->WDOGLOAD = PWM_PFC_CHNL->TBPRD * 12; // 6 PWM period
  WDT0->WDOGCONTROL_b.RSTEN = 1;  // Reset Enable
  WDT0->WDOGCONTROL_b.INTEN = 1;  // Enable Interrupt and Start Counter
//  while(1)
//  {
//    while(WDT0->WDOGRIS_b.WDOGINT == 0);
//    WDT0->WDOGINTCLR = 1;
//    LED1_FLASH;
//  }
}

///**
//  * @brief  Timer Initialization.
//  */
//void mg_TimerInit(void)
//{
//  TIMER_TmrConfig(0,1000,1);     // 1000uS
//  TIMER_TmrConfig(1,50000000,1); // 50S
//  TIMER_TmrConfig(2,50000000,0); // 50S
//}



/**
  * @brief  ERU Initialization.
  */
void mg_EruInit(void)
{
  ACCESS_ENABLE;
  /* ERU0 CONFIG, used as VDC Cycle-by-cycle protect */
  ERU->ERUINSEL_b.in0_selb  = 0;    /**< adc high cmp0 int(OCL trig source)             */
  ERU->ERUINCTRL0_b.BPOL    = 0;    /**< directly                                       */
  ERU->ERUINCTRL0_b.ERSOSEL = 1;    /**< ERS0O = b                                      */
  ERU->ERUINCTRL0_b.RE      = 1;    /**< rising edge detect enable                      */
  ERU->ERUINCTRL0_b.LVL_DET = 1;    /**< level detect rebuild enable                    */
  ERU->ERUOUTCTRL0_b.IPEN0  = 1;    /**< ETL0.FL is included in the pattern detection   */
  ERU->ERUOUTCTRL0_b.GP     = 2;    /**< GOUT = PDOUT, PWM_CTRIP[0]                     */

  /* ERU2 CONFIG, used as PMSM h/w fault protect */
  ERU->ERUINSEL_b.in2_selb  = 2;    /**< GPIO33(PMSM H/W FAULT signal)                  */
  ERU->ERUINCTRL2_b.BPOL    = 0;    /**< directly                                       */
  ERU->ERUINCTRL2_b.ERSOSEL = 1;    /**< ERS2O = b                                      */
  ERU->ERUINCTRL2_b.FE      = 1;    /**< Falling edge detect enable                     */
  ERU->ERUINCTRL2_b.LVL_DET = 1;    /**< level detect rebuild enable                    */
  ERU->ERUOUTCTRL2_b.IPEN2  = 1;    /**< ETL2.FL is included in the pattern detection   */
  ERU->ERUOUTCTRL2_b.GP     = 2;    /**< GOUT = PDOUT, PWM_CTRIP[2]                     */
  ACCESS_DISABLE;
}


/**
  * @brief      read eeprom data and change eeprom data to real param
  * @param[in]  void : None.
  * @param[out] void : None.
  * @retval     void : None.
  * @par        Example:
  * -This example shows how to call the function:
  * @code
  * mg_ReadIIcData();
  * @endcode
  * @warning:
*/
void mg_ReadIIcData(void)
{
//  uint16_t i, u16Crc;

////  // Write eeprom with keil
////  USERPARA_SetDefaultEepromParam(&g_sUserParam);
//////  IIC_WRITE_ENABLE;
////  IIC_WritePage(mg_u8EepromWriteData,384,0); // Write haixin control param.
////  IIC_WritePage((uint8_t *)&g_sUserParam,sizeof(g_sUserParam),384); // Write pmsm and pfc param.
//////  IIC_WRITE_DISABLE;

//  #if EEPROM_READ_EN
//    IIC_ReadPage((uint8_t *)&g_sUserParam, sizeof(sUserParam), 384);  // Read pmsm and pfc param.
//    u16Crc = USERPARA_CrcDataGet((uint8_t *)(&g_sUserParam),sizeof(sUserParam)-2);

//    if((g_sUserParam.u16CrcChkval != u16Crc)||(u16Crc == 0)){
//      g_u8EepromErrFlg = 1;
//      USERPARA_SetDefaultEepromParam(&g_sUserParam);
//    }
//  #else
//    g_u8EepromErrFlg = 0;
//    USERPARA_SetDefaultEepromParam(&g_sUserParam);
//  #endif

//  PmsmUserParaInit(&g_sPmsmUserPara, &g_sUserParam);
//  FanUserParaInit (&g_sFanUserPara,  &g_sUserParam);
//  PfcUserParaInit (&g_sPfcUserPara,  &g_sUserParam);
}

/**
  * @brief   irq set init for core0.
  */
void mg_SetIRQ(void)
{
  __disable_irq();

  NVIC_ClearPendingIRQ(GPIO_IRQn);
  NVIC_EnableIRQ(GPIO_IRQn);
  NVIC_SetPriority(GPIO_IRQn,0);

  NVIC_ClearPendingIRQ(ECAP0_IRQn);
  NVIC_SetPriority(ECAP0_IRQn,0);
  NVIC_EnableIRQ(ECAP0_IRQn);

  #ifndef DUAL_CORE
    NVIC_ClearPendingIRQ(ADC2_IRQn);
    NVIC_EnableIRQ(ADC2_IRQn);
    NVIC_SetPriority(ADC2_IRQn,1);
  #endif

  NVIC_ClearPendingIRQ(PWM0_IRQn);
  NVIC_EnableIRQ(PWM0_IRQn);
  NVIC_SetPriority(PWM0_IRQn,2);

  NVIC_ClearPendingIRQ(UART0_IRQn);
  NVIC_SetPriority(UART0_IRQn,2);
  NVIC_EnableIRQ(UART0_IRQn);

  NVIC_ClearPendingIRQ(TIMER0_IRQn);
  NVIC_SetPriority(TIMER0_IRQn,3);
  NVIC_EnableIRQ(TIMER0_IRQn);

  NVIC_ClearPendingIRQ(SysTick_IRQn);
  NVIC_SetPriority(SysTick_IRQn,3);
//  NVIC_EnableIRQ(SysTick_IRQn);     // Config in SysTick_Config function.

  NVIC_ClearPendingIRQ(DMA_IRQn);
  NVIC_SetPriority(DMA_IRQn,3);
  NVIC_EnableIRQ(DMA_IRQn);

  __enable_irq();
}


/**
  * @brief   irq set init for core1.
  */
void mg_SetIRQ_c1(void)
{
  __disable_irq();

  NVIC_ClearPendingIRQ(ADC2_IRQn);
  NVIC_EnableIRQ(ADC2_IRQn);
  NVIC_SetPriority(ADC2_IRQn,1);

  NVIC_ClearPendingIRQ(PWM3_IRQn);
  NVIC_EnableIRQ(PWM3_IRQn);
  NVIC_SetPriority(PWM3_IRQn,2);

  __enable_irq();
}


/**
  * @brief  Initialize System Clock, Systick, cache, etc.
  */
void mg_DeviceSystemInit(void)
{
//  CHIP_KEY_ENABLE;
//  CHIPCTL->POWER_CTRL_b.MVRSEL = 1;

  /* System Clock Init */
  SysClockConfig(SRCSEL_PLL,PLLSRC_RCH15M,CLKDIV_6,PLLMULT_28); // 15 * 28 / 6 = 70MHz
//  SysClockConfig(SRCSEL_PLL,PLLSRC_OSC,CLKDIV_4,PLLMULT_24);  // 12*24/4=72Mhz
  SysClkDivSel(CLKDIV_1,CLKDIV_1,CLKDIV_1,CLKDIV_1);

  /* System Core Clock Variables Update */
  SystemCoreClockUpdate();

  /* SysTick Init */
  SysTick_Config(SystemAhbClock/1000);

  if(CHIPCTL->STATUS0_b.POR)
  {
    CHIP_KEY_ENABLE;
    CHIPCTL->STATUS0 = 0xa05fcccc;  // Clear status0
  }

  /* Cache Init */
  mg_CacheInit();

  /* Coproc Init */
  MULT_INIT_MACRO()
  DIV_INIT_MACRO()
  CORDIC_INIT_MACRO()
}


/*******************************************************************************
 * Global function for the current project
 ******************************************************************************/

/**
  * @brief     init all data for the function.
  * @param[in]  void : None.
  * @retval     void : None
  * @par        None
  * @par        Example:
  * This example shows how to call the function:
  * @code
  * INIT_DeviceInit();
  * @endcode
  * @Note:
  */
void INIT_DeviceInit(void)
{
  /* System Clock, Flash&SRAM, Mult&Div Init */
  mg_DeviceSystemInit();

  /* GPIO Init */
  GPIO_GpioInit();

  /* Read user parameters from eeprom */
//  mg_ReadIIcData();

  /* Module Init */
  PfcInitFunction();
  PmsmInitFunction();
  #if FAN_CTRL_EN
    FanInitFunction();
  #endif

  /* Timer Init */
  TIMER_TmrConfig(0,1000,1);     // 1000uS

  /* DMA Init */
  DMA_Init();

  /* UART Init */
  Uart0Init(115200);
  Uart1Init(300);
  Uart2Init(2400);

  /* ERU init */
  mg_EruInit();

  /* Debug Tool Init */
  WAVE_Init();
  DBG_ParamInit();

  /* ADC Init */
  BSP_AdcConfig();

  /* PWM Init */
  BSP_PwmInit();

  /* EEV Init */
  mg_EEV_Init(0);

  /* Watch Dog Timer Init */
  mg_WdtInit();

  /* NVIC Init */
  mg_SetIRQ();
}


void INIT_DeviceInit_c1(void)
{
  /* MULT&DIV Init */
  MULT_INIT_MACRO()
  DIV_INIT_MACRO()  

  /* NVIC Init */
  mg_SetIRQ_c1();
}
/*---------------------------------- End of the file ---------------------------------*/
